fix(ext-agents): select a compatible Python for azd ai agent run instead of first on PATH#9012
fix(ext-agents): select a compatible Python for azd ai agent run instead of first on PATH#9012glharper wants to merge 2 commits into
azd ai agent run instead of first on PATH#9012Conversation
…first on PATH azd ai agent run's pip fallback resolved Python via findSystemPython, which returned the first of python3/python/py on PATH and then hard-failed in checkPythonVersion if that interpreter was too old. On Windows, python.exe is frequently an older version (e.g. 3.11) even when a newer Python (3.13) is installed and selectable via the 'py -3' launcher, so 'azd ai agent run' failed with 'Python 3.13+ is required (found 3.11.9)'. findSystemPython now probes multiple candidates -- preferring the Windows 'py -3' launcher, which selects the newest installed Python 3 -- and checks each one's version, returning the first that satisfies the minimum runtime (>= 3.13). When every candidate is too old, the error names the newest version found. The interpreter is modeled as an executable plus launcher args so a 'py -3' selection is carried through to venv creation. Fixes #8954 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
There was a problem hiding this comment.
Pull request overview
This PR fixes azd ai agent run on Windows when multiple Python installations exist by selecting a Python interpreter that satisfies the agent runtime requirement (>= 3.13) instead of using the first python found on PATH, aligning the pip fallback behavior with the existing uv path.
Changes:
- Replace the
pip-path Python resolver with a version-aware probe that tries multiple candidates (preferringpy -3on Windows) and selects the first compatible interpreter. - Add unit tests covering interpreter selection behavior, version parsing, and error cases.
- Add an Unreleased changelog entry for the fix.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
cli/azd/extensions/azure.ai.agents/internal/cmd/run.go |
Implements a version-aware Python interpreter resolver and uses it for venv creation in the pip fallback path. |
cli/azd/extensions/azure.ai.agents/internal/cmd/run_test.go |
Adds tests for version parsing and interpreter selection logic, including the Windows repro scenario. |
cli/azd/extensions/azure.ai.agents/CHANGELOG.md |
Documents the bug fix in the extension’s Unreleased notes. |
jongio
left a comment
There was a problem hiding this comment.
Version-aware interpreter resolution with DI for testability, correct Windows launcher ordering, and informative error messages. The slices.Clone in command() prevents arg slice mutation. Looks correct.
RickWinter
left a comment
There was a problem hiding this comment.
This replaces first-python-on-PATH resolution with a version-aware resolver. findSystemPython now probes an ordered candidate set (on Windows the py -3 launcher first, which selects the newest installed Python 3) and returns the first that satisfies >= 3.13, modeling an interpreter as path plus launcher args so a py -3 selection carries through to venv creation. This is the right shape and makes the pip path behave like the uv path's --python ">=3.13" constraint.
The selection logic is factored behind an injected version function and covered directly: the Windows repro (py -3 picks 3.13 over a 3.11 python), skip-too-old, the newest-incompatible error naming the version found, unparseable-version skip, and the empty case. The too-old error now names the newest version on the machine, which is a real usability improvement over the prior hard-fail on whichever python came first.
No correctness or security concerns. Build, vet, lint, and the internal/cmd tests pass.
Disposition: no blockers.
…onstants The uv path hardcoded --python ">=3.13" while the pip path used the minPythonMajor/minPythonMinor constants, so the two could drift out of sync. Add minPythonUvSpec(), which builds the uv specifier from the constants, use it in the uv venv command, and add a test asserting it tracks the constants. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Good call -- addressed in ff179a5. Added |
Summary
On Windows,
azd ai agent runfails withPython 3.13+ is required (found 3.11.9)even when Python 3.13 is installed and selectable via the Windows Python launcher (py -0reports3.13 *). The project declaresruntime: python_3_13inazure.yaml.Root cause: the
pipfallback path resolves Python viafindSystemPython, which returned the first ofpython3/python/pyfound onPATHand then hard-failed incheckPythonVersionif that interpreter was too old. WhenPython311precedesPython313onPATH,python.exeis 3.11 and the resolver never falls through to thepylauncher that would locate 3.13.Fix
findSystemPythonnow probes multiple candidates and checks each one's version, returning the first that satisfies the minimum supported runtime (>= 3.13):py -3launcher, which selects the newest installed Python 3 (rather than whicheverpython.exeis first onPATH), then falls back topython3,python, and the defaultpy.pythonInterpreter{path, args}), so apy -3selection is carried through to venv creation (py -3 -m venv ...).This makes the
pippath behave like theuvpath, which already resolves a compatible interpreter viauv venv --python ">=3.13".Changes
internal/cmd/run.go— replacefindSystemPython/checkPythonVersionwith a version-aware resolver:pythonInterpreter(+command),pythonCandidates,pythonVersion,pythonVersionOK,firstCompatiblePython, and a rewiredfindSystemPython. Minimum runtime is now the namedminPythonMajor/minPythonMinorconstants. The pip-path call site uses the resolved interpreter directly.internal/cmd/run_test.go— unit tests for the selection logic (firstCompatiblePythonwith an injected version function, covering the Windows repro, skip-too-old, newest-incompatible error, unparseable-version skip, and empty cases),pythonVersionOK,pythonVersion, and the no-Python error.CHANGELOG.md— Unreleased entry.Testing
go build ./...,go vet,golangci-lint run ./internal/cmd/— cleango test ./internal/cmd/ -count=1— passgofmtandcspellon changed files — cleanFixes #8954